#include "implementations/KeyManager.h"
#include "interfaces/KeyListener.h"

vnav::graphics::KeyManager* vnav::graphics::KeyManager::m_Self = NULL;

vnav::graphics::KeyManager::KeyManager()
{
	m_Keys[KEY_W] = false;
	m_Keys[KEY_S] = false;
	m_Keys[KEY_A] = false;
	m_Keys[KEY_D] = false;

	m_Keys[KEY_UP] = false;
	m_Keys[KEY_DOWN] = false;
	m_Keys[KEY_LEFT] = false;
	m_Keys[KEY_RIGHT] = false;

	m_Keys[KEY_Q] = false;
	m_Keys[KEY_E] = false;
	m_Keys[KEY_Z] = false;
	m_Keys[KEY_X] = false;

	m_Keys[KEY_UNKNOWN] = false;
}

vnav::graphics::KeyManager::~KeyManager()
{
}

vnav::graphics::KeyManager* vnav::graphics::KeyManager::instance()
{
	if (m_Self == NULL)
		m_Self = new vnav::graphics::KeyManager;
	return m_Self;
}

void vnav::graphics::KeyManager::keyPressed(SDLKey key)
{
	KeyType keyType = getKeyType(key);
	m_Keys[keyType] = true;
	
	std::vector<KeyListener*>::iterator it = m_keyListeners.begin();
	for (; it != m_keyListeners.end(); ++it)
	{
		if (*it)
		{
			(*it)->onKeyPressEvent(keyType);
		}
	}
}

void vnav::graphics::KeyManager::keyReleased(SDLKey key)
{
	KeyType keyType = getKeyType(key);
	m_Keys[keyType] = false;

	std::vector<KeyListener*>::iterator it = m_keyListeners.begin();
	for (; it != m_keyListeners.end(); ++it)
	{
		if (*it)
		{
			(*it)->onKeyReleaseEvent(keyType);
		}
	}
}

bool vnav::graphics::KeyManager::isKeyDown(vnav::graphics::KeyManager::KeyType key)
{
	return m_Keys[key];
}

void vnav::graphics::KeyManager::registerOnKeyEvent(KeyListener* listener)
{
	if (listener)
		m_keyListeners.push_back(listener);
}

void vnav::graphics::KeyManager::unregisterOnKeyEvent(KeyListener* listener)
{
	std::vector<KeyListener*>::iterator it = m_keyListeners.end();
	for (std::vector<KeyListener*>::iterator iter = m_keyListeners.begin();
		iter != m_keyListeners.end(); ++iter)
	{
		if (listener == *iter)
		{
			it = iter; break;
		}
	}
	if (it != m_keyListeners.end())
	{
		m_keyListeners.erase(it);
	}
}

vnav::graphics::KeyManager::KeyType vnav::graphics::KeyManager::getKeyType(SDLKey key)
{
	switch(key)
	{
	case SDLK_w: return KEY_W;
	case SDLK_s: return KEY_S;
	case SDLK_a: return KEY_A;
	case SDLK_d: return KEY_D;
	case SDLK_UP: return KEY_UP;
	case SDLK_DOWN: return KEY_DOWN;
	case SDLK_LEFT: return KEY_LEFT;
	case SDLK_RIGHT: return KEY_RIGHT;
	case SDLK_e: return KEY_E;
	case SDLK_q: return KEY_Q;
	case SDLK_z: return KEY_Z;
	case SDLK_x: return KEY_X;
	default: return KEY_UNKNOWN;
	}
}